from __future__ import annotations

import typing as t
from enum import IntEnum

from app.lib.model import Model
from tortoise import fields
from tortoise.query_utils import Q


class PermissionEnum(IntEnum):
    PUBLISH_ARTICLES = 100  # 发表文章
    PUBLISH_COMMENT = 101  # 评论
    BLOCK_USER = 102  # 拉黑用户
    BAN_USER = 103  # 封禁用户
    MANAGE_PERMISSION = 104  # 权限管理


DEFAULT_USER_PERMISSION = [
    PermissionEnum.PUBLISH_ARTICLES,
    PermissionEnum.PUBLISH_COMMENT,
    PermissionEnum.BLOCK_USER,
]


class Permission(Model):
    class Meta:
        table = "Permission"

    auto_id = fields.IntField(pk=True)
    number = fields.IntEnumField(PermissionEnum, description="数字权限码")

    @classmethod
    async def ensure_many(cls, permission_enums: set[PermissionEnum]):
        existed_permissions = await cls.get_permissions(permission_enums)

        existed_numbers = {permission.number for permission in existed_permissions}
        not_existed_numbers = sorted(list(permission_enums - existed_numbers))

        permission_objs = [cls(number=number) for number in not_existed_numbers]

        if permission_objs:
            await cls.bulk_create(permission_objs)

    @classmethod
    async def get_permissions(
        cls, permission_enums: t.Iterable[PermissionEnum]
    ) -> t.List[Permission]:
        numbers = {permission_enum.value for permission_enum in permission_enums}
        existed_permissions: t.List[cls] = await cls.filter(Q(number__in=numbers)).all()
        return existed_permissions
